<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">
  <meta name="google-site-verification" content="yF8HXsFuCTrePDFRnSkN2kkzV2ypBjtywzXsfVXOOV8">
  <meta name="baidu-site-verification" content="VxrVAiQAZ9">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yang0033.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":true,"preload":true},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="gitflow 进阶规范git cz通过工具 git-cz 规范 git commit 提交信息。 使用 1$ npm install -g git-cz  git commit 的讲究通过工具使用可以看出 git 本身及 github 社区对 git 提交单位及提交信息是有非常讲究的要求的，这或许也是我之前给国外 repo 提 PR 被dis的主要原因😅。">
<meta property="og:type" content="article">
<meta property="og:title" content="gitflow 规范及工具整理">
<meta property="og:url" content="http://yang0033.gitee.io/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/index.html">
<meta property="og:site_name" content="SuperYang&#96;s Blog">
<meta property="og:description" content="gitflow 进阶规范git cz通过工具 git-cz 规范 git commit 提交信息。 使用 1$ npm install -g git-cz  git commit 的讲究通过工具使用可以看出 git 本身及 github 社区对 git 提交单位及提交信息是有非常讲究的要求的，这或许也是我之前给国外 repo 提 PR 被dis的主要原因😅。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-835478a8f1297d63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-000558fbf1119df7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-a98d59f7774ce303.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-9f83b569bef75499.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-31859b36d3decae8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-7f3db1b3af7cd11a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-c13e06a9f27735c5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="og:image" content="https://upload-images.jianshu.io/upload_images/1445110-cf480196748cc7e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">
<meta property="article:published_time" content="2020-03-16T08:29:00.000Z">
<meta property="article:modified_time" content="2020-07-09T08:00:27.048Z">
<meta property="article:author" content="SuperYang">
<meta property="article:tag" content="工程管理">
<meta property="article:tag" content="DevOps">
<meta property="article:tag" content="lint">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://upload-images.jianshu.io/upload_images/1445110-835478a8f1297d63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240">

<link rel="canonical" href="http://yang0033.gitee.io/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>gitflow 规范及工具整理 | SuperYang`s Blog</title>
  
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-71812998-3"></script>
    <script>
      if (CONFIG.hostname === location.hostname) {
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-71812998-3');
      }
    </script>


  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?8ff3295288514de6f89f314c23ee40ab";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">SuperYang`s Blog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">落魄程序员在线炒饭</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
        <li class="menu-item menu-item-message">

    <a href="/message/" rel="section"><i class="fa fa-music fa-fw"></i>留言板 | Music</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://yang0033.gitee.io/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="https://tva2.sinaimg.cn/crop.259.17.290.290.180/c2abdfa9jw8ez7appr3p2j20g40a2t91.jpg?KID=imgbed,tva&Expires=1594186820&ssig=BdxhDdi1Ti">
      <meta itemprop="name" content="SuperYang">
      <meta itemprop="description" content="牛肉炒饭不要香菜，老板收钱">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="SuperYang`s Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          gitflow 规范及工具整理
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-03-16 16:29:00" itemprop="dateCreated datePublished" datetime="2020-03-16T16:29:00+08:00">2020-03-16</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-07-09 16:00:27" itemprop="dateModified" datetime="2020-07-09T16:00:27+08:00">2020-07-09</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/iOS/" itemprop="url" rel="index"><span itemprop="name">iOS</span></a>
                </span>
            </span>

          
            <span id="/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/" class="post-meta-item leancloud_visitors" data-flag-title="gitflow 规范及工具整理" title="阅读次数">
              <span class="post-meta-item-icon">
                <i class="fa fa-eye"></i>
              </span>
              <span class="post-meta-item-text">阅读次数：</span>
              <span class="leancloud-visitors-count"></span>
            </span>
  
  <span class="post-meta-item">
    
      <span class="post-meta-item-icon">
        <i class="far fa-comment"></i>
      </span>
      <span class="post-meta-item-text">Valine：</span>
    
    <a title="valine" href="/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/#valine-comments" itemprop="discussionUrl">
      <span class="post-comments-count valine-comment-count" data-xid="/2020/03/16/gitflow%20%E8%A7%84%E8%8C%83%E5%8F%8A%E5%B7%A5%E5%85%B7%E6%95%B4%E7%90%86/" itemprop="commentCount"></span>
    </a>
  </span>
  
  <br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="far fa-file-word"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>5.9k</span>
            </span>
            <span class="post-meta-item" title="阅读时长">
              <span class="post-meta-item-icon">
                <i class="far fa-clock"></i>
              </span>
                <span class="post-meta-item-text">阅读时长 &asymp;</span>
              <span>5 分钟</span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="gitflow-进阶规范"><a href="#gitflow-进阶规范" class="headerlink" title="gitflow 进阶规范"></a>gitflow 进阶规范</h1><h2 id="git-cz"><a href="#git-cz" class="headerlink" title="git cz"></a>git cz</h2><p>通过工具 <a href="https://github.com/streamich/git-cz" target="_blank" rel="noopener">git-cz</a> 规范 git commit 提交信息。</p>
<p>使用</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -g git-cz</span><br></pre></td></tr></table></figure>

<h3 id="git-commit-的讲究"><a href="#git-commit-的讲究" class="headerlink" title="git commit 的讲究"></a>git commit 的讲究</h3><p>通过工具使用可以看出 git 本身及 github 社区对 git 提交单位及提交信息是有非常讲究的要求的，这或许也是我之前给国外 repo 提 PR 被dis的主要原因😅。</p>
<a id="more"></a> 
<h4 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h4><p>可以通过命令快速对 log 进行筛选</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git log &lt;last release&gt; HEAD --grep feat # 通过 feat 关键在查询功能变更</span><br></pre></td></tr></table></figure>

<p>具体如下：</p>
<ul>
<li><p>如何界定何时提交一个 commit，如何定义 commit 提交目标</p>
<ul>
<li>详细待我口述</li>
</ul>
</li>
<li><p>如何书写 git message</p>
<ul>
<li>message 其实包含三部分: header、body、footer</li>
<li>header 包含两部分: type、subject<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&lt;type&gt;[(&lt;scope&gt;)]: &lt;emoji&gt; &lt;subject&gt; &#x2F;&#x2F; header 部分</span><br><span class="line">[BLANK LINE] &#x2F;&#x2F;空行</span><br><span class="line">[body] &#x2F;&#x2F; 长描述</span><br><span class="line">[BLANK LINE] </span><br><span class="line">[breaking changes] &#x2F;&#x2F; </span><br><span class="line">[BLANK LINE]</span><br><span class="line">[footer]</span><br></pre></td></tr></table></figure>
其中，只有 header 为强制 message 必选项。<br>其中 header 限制为 50 个字符，其他每行不超过72个字符，主要为了美观，避免换行</li>
</ul>
</li>
<li><p>subject</p>
<ul>
<li>动词开头，第一人称一般现在时祈使句。比如 change 而不是 changes 或 changed</li>
<li>首字母小写</li>
<li>结尾不加句号（.）</li>
</ul>
</li>
<li><p>BREAKING CHANGE (不兼容改动)<br>当代码改动与上个版本不兼容时，需要对 BREAKING CHANGE 进行描述，通常会记录对改动的描述，改动的原因，以及迁移的方法。</p>
</li>
<li><p>关闭 Issue<br>当前 commit 针对某个 issue 时，可以填写 Issue id</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">#234</span><br></pre></td></tr></table></figure>


</li>
</ul>
<p>阮一峰老师也有一篇<a href="http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html" target="_blank" rel="noopener">文章</a>，和另一篇知乎的<a href="https://juejin.im/post/5afc5242f265da0b7f44bee4" target="_blank" rel="noopener">文章</a>感兴趣可以细看。</p>
<h2 id="husky-（自动化神器，git-hook-完美辅助）"><a href="#husky-（自动化神器，git-hook-完美辅助）" class="headerlink" title="husky （自动化神器，git hook 完美辅助）"></a>husky （自动化神器，git hook 完美辅助）</h2><p>知乎上有篇<a href="https://zhuanlan.zhihu.com/p/35913229" target="_blank" rel="noopener">文章</a>大概讲了下这个神器。<br>主要能力是通过安装 husky npm 包及工程根目录的 package.json 部署 git hook。<br>hook 管理同 repo 一起，避免尴尬的 git hook 复制粘贴式维护，并且支持 node 脚本。<br>husky 配置已在单独feat分支配置完毕，有兴趣可以看上面的文章和 github 文档学习。</p>
<ul>
<li>使用<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install husky --save-dev &#x2F;&#x2F; 注意一定要用 --save-dev 安装到本地，而非 -g 全局</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h2 id="lint-staged"><a href="#lint-staged" class="headerlink" title="lint-staged"></a>lint-staged</h2><p>那么问题来了，有了 husky，可以书写一些提交的校验脚本，但是却无法区分校验的内容是新提交的还是旧的已经有的。</p>
<p>不用怕，既然我们能想到，社区一定会有人遇到同样的问题。祭出终极杀手锏，<a href="https://github.com/okonet/lint-staged" target="_blank" rel="noopener"><strong>lint-staged</strong></a>。</p>
<p>这个东东一定要配合着 husky 使用才有效果，一样，也是为了提供在提交时进行预处理的能力衍生的工具。</p>
<ul>
<li>使用<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install lint-staged --save-dev &#x2F;&#x2F; 注意一定要用 --save-dev 安装到本地，而非 -g 全局</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h2 id="问题及bug处理"><a href="#问题及bug处理" class="headerlink" title="问题及bug处理"></a>问题及bug处理</h2><ol>
<li>当lint工具误判或提交文件太多导致出错时，可在操作后面加上 –no-verify 绕过lint检查。</li>
</ol>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><ul>
<li><a href="https://github.com/tomchentw/imagemin-lint-staged" target="_blank" rel="noopener">imagemin-lint-staged</a></li>
<li><a href="https://github.com/PaicFE/blog/issues/10" target="_blank" rel="noopener">手牵手使用Husky &amp; Nodejs自定义你的Git钩子</a></li>
<li><a href="https://github.com/zhangyu921/blog/issues/4" target="_blank" rel="noopener">利用 ESlint、lint-staged 半自动提升项目代码质量</a></li>
<li><a href="https://juejin.im/post/592615580ce463006bf19aa0" target="_blank" rel="noopener">用 husky 和 lint-staged 构建超溜的代码检查工作流</a></li>
<li><a href="https://github.com/collections/clean-code-linters" target="_blank" rel="noopener">Clean code linter</a></li>
<li><a href="https://juejin.im/post/5afc5242f265da0b7f44bee4" target="_blank" rel="noopener">优雅的提交你的 Git Commit Message</a></li>
<li><a href="https://zhuanlan.zhihu.com/p/35913229" target="_blank" rel="noopener">【工具推荐】使用 husky 避免糟糕的 git commit</a></li>
</ul>
<h1 id="github-flow-VS-gitlab-flow-【三稿】"><a href="#github-flow-VS-gitlab-flow-【三稿】" class="headerlink" title="github-flow VS gitlab-flow 【三稿】"></a>github-flow VS gitlab-flow 【三稿】</h1><ul>
<li><p>主干分支开发</p>
</li>
<li><p>特性分支开发</p>
</li>
</ul>
<h2 id="git-flow"><a href="#git-flow" class="headerlink" title="git flow"></a>git flow</h2><p>我们在 Google 上查关键词“branch model”（也就是“分支模型”），有一篇排名比较靠前的文章“A successful Git branching model”，它介绍了 Git Flow 模型。</p>
<p>Git 刚出来的那些年，可参考的模型不多，所以 Git Flow 模型在 2011 年左右被大家当作了推荐的分支模型，至今也还有项目团队在使用。然而，Git Flow 烦琐的流程也被许多研发团队吐槽，大家普遍认为 hotfix 和 release 分支显得多余，平时都不会去用。</p>
<p><img src="https://upload-images.jianshu.io/upload_images/1445110-835478a8f1297d63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="git flow"></p>
<p>简单解释一下：</p>
<h3 id="master"><a href="#master" class="headerlink" title="master"></a>master</h3><p>主干分支，用于保存已经发布的稳定代码。图中按时间线该分支已经从 0.1、0.2 发展到了 1.0版本。</p>
<h3 id="develop"><a href="#develop" class="headerlink" title="develop"></a>develop</h3><p>开发主干分支，从 master 分支切出，用于平时的集成开发和集成测试，其中的代码主要用于下一次 relaese 发布，图中的节点表示的是 1.0 的下一个版本。</p>
<h3 id="feature-branches"><a href="#feature-branches" class="headerlink" title="feature branches"></a>feature branches</h3><p>用于将来要发布的某个发布版本准备的 feature 特性分支，从 develop 分支切出。这个分支的含义非常丰富。举例：图中从左往右第一个分支，他的feature特性只是说会在将来某个版本上，但没有确定，一般以做完的时间为主。而第二个feature分支却是下个版本主要的特性分支代码。</p>
<h3 id="release-branches"><a href="#release-branches" class="headerlink" title="release branches"></a>release branches</h3><p>用于做发版的分支，一般承载下个版本的代码发布，当然可以存在多个。在某个节点要发版时从 develop 切出。切出后这个分支只会为之后版本发布做 bug fix 相关的 commit 提交。在发版结束后，会同时向 develop 分支和 master 进行合并。并在 master 打 tag。release 分支即可删除。</p>
<h3 id="hotfix-branches"><a href="#hotfix-branches" class="headerlink" title="hotfix branches"></a>hotfix branches</h3><p>一般用于发布后版本的 bug 修复，例如图中，由于要修复 0.1 的一个bug，从 master 0.1 tag处切出 hotfix分支，修复完成后，将 hotfix 合入 develop 分支和 master 分支，在 master 打tag，并删除 hotfix 分支。</p>
<h2 id="GitHub-Flow"><a href="#GitHub-Flow" class="headerlink" title="GitHub Flow"></a>GitHub Flow</h2><p>GitHub Flow 是 GitHub 所使用的一种简单流程。该流程只使用 master 和特性分支，并借助 GitHub 的 pull request 功能。</p>
<p><img src="https://upload-images.jianshu.io/upload_images/1445110-000558fbf1119df7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="github flow"></p>
<p><strong>在 GitHub Flow 中，master 分支中包含稳定的代码，它已经或即将被部署到生产环境。任何开发人员都不允许把未测试或未审查的代码直接提交到 master 分支。对代码的任何修改，包括 Bug 修复、热修复、新功能开发等都在单独的分支中进行。不管是一行代码的小改动，还是需要几个星期开发的新功能，都采用同样的方式来管理。</strong></p>
<p>当需要修改时，从 master 分支创建一个新的分支，所有相关的代码修改都在新分支中进行。开发人员可以自由地提交代码和提交到远程仓库。</p>
<p>当新分支中的代码全部完成之后，通过 GitHub 提交一个新的 pull request。团队中的其他人员会对代码进行审查，提出相关的修改意见。由持续集成服务器（如 Jenkins）对新分支进行自动化测试。当代码通过自动化测试和代码审查之后，该分支的代码被合并到 master 分支。再从 master 分支部署到生产环境。</p>
<p>GitHub Flow 的好处在于非常简单实用，开发人员需要注意的事项非常少，很容易形成习惯。当需要修改时，只要从 master 分支创建新分支，完成之后通过 pull request 和相关的代码审查，合并回 master 分支就可以了。</p>
<h3 id="Gitlab-flow"><a href="#Gitlab-flow" class="headerlink" title="Gitlab flow"></a>Gitlab flow</h3><p>上面提到的 GitHub Flow，适用于特性分支合入 master 后就能马上部署到线上的这类项目，但并不是所有团队都使用 GitHub 或使用 pull request 功能，而是使用开源平台 GitLab，特别是对于公司级别而言，代码作为资产，不会随意维护在较公开的 GitHub 上（除非采用企业版）。</p>
<p>GitLab Flow 针对不同的发布场景，在 GitHub Flow（特性分支加 master 分支）的基础上做了改良，额外衍生出了三个子类模型，如表 2 所示。</p>
<p><img src="https://upload-images.jianshu.io/upload_images/1445110-a98d59f7774ce303.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="表2 Gitlab Flow 的三个分支"><br><img src="https://upload-images.jianshu.io/upload_images/1445110-9f83b569bef75499.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图3 带生产分支的 GitLab Flow"><br><img src="https://upload-images.jianshu.io/upload_images/1445110-31859b36d3decae8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图4 带环境分支的 GitLab Flow"><br><img src="https://upload-images.jianshu.io/upload_images/1445110-7f3db1b3af7cd11a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="图5 带发布分支的 GitLab Flow"></p>
<p>GitLab Flow 的特性分支合入 master 用的是“Merge Request”，功能与 GitHub Flow 的“pull request”相同，这里不再赘述。</p>
<p>通过 Git Flow、GitHub Flow 和 GitLab Flow（3 个衍生类别） 这几个具体模型的介绍，我给你总结一下特性分支开发的优缺点。如表 3 所示。<br><img src="https://upload-images.jianshu.io/upload_images/1445110-c13e06a9f27735c5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image"></p>
<h2 id="选出最合适的分支策略"><a href="#选出最合适的分支策略" class="headerlink" title="选出最合适的分支策略"></a>选出最合适的分支策略</h2><p>上面我跟你讲到的分支模型，都是 IT 研发领域比较流行的。虽然有些策略带上了代码平台的标识，如 GitHub Flow，但并不意味着该策略仅限于 GitHub 代码平台使用，你完全可以在自己搭建的代码平台上使用这些策略。</p>
<p>接下来，我就总体归纳一下什么情况下应该选择什么样的分支策略。如表 4 所示。</p>
<p><img src="https://upload-images.jianshu.io/upload_images/1445110-cf480196748cc7e2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image"></p>
<h1 id="SwiftLint-使用"><a href="#SwiftLint-使用" class="headerlink" title="SwiftLint 使用"></a>SwiftLint 使用</h1><p>热烈庆祝 SwiftLint 加入 lint-staged 豪华午餐 🎉 🎉 🎉<br>（之后对项目 swift 整理治理后，会考虑集成到编译脚本中，每次build都会lint检测）<br>简单说一下需要注意的问题。<br>首先 SwiftLint 使用 lint-staged 集成，对开发人员基本无感知，在代码提交时会进行 lint操作，并同时进行检测。</p>
<h2 id="lint-成功"><a href="#lint-成功" class="headerlink" title="lint 成功"></a>lint 成功</h2><p>如果你的代码符合 <a href="https://github.com/realm/SwiftLint/blob/e312b06f713bd660b64526e69391eab7ecbc1e19/Rules.md" target="_blank" rel="noopener">lint 规则</a>。<br>恭喜，你的提交会正常进入git commit log。</p>
<h2 id="lint-失败"><a href="#lint-失败" class="headerlink" title="lint 失败"></a>lint 失败</h2><p>你会看到如下提示</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">husky &gt; pre-commit (node v8.9.1)</span><br><span class="line">  ↓ Stashing changes... [skipped]</span><br><span class="line">    → No partially staged files found...</span><br><span class="line">  ❯ Running linters...</span><br><span class="line">    ↓ Running tasks for *.&#123;png,jpeg,jpg,gif,svg&#125; [skipped]</span><br><span class="line">      → No staged files match *.&#123;png,jpeg,jpg,gif,svg&#125;</span><br><span class="line">    ❯ Running tasks for *.swift</span><br><span class="line">      ✖ Pods/SwiftLint/swiftlint lint</span><br><span class="line"></span><br><span class="line">✖ Pods/SwiftLint/swiftlint lint found some errors. Please fix them and try committing again.</span><br><span class="line">⛔️ Line 27: Line should be 120 characters or less: currently 218 characters</span><br><span class="line">⚠️ Line 40: Line should be 120 characters or less: currently 128 characters</span><br><span class="line">⚠️ Line 36: Line should be 120 characters or less: currently 194 characters</span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">Linting Swift files at paths /Users/chaoyang/Dev/YCMath_New_iOS/b.swift</span><br><span class="line">Linting 'b.swift' (1/1)</span><br><span class="line">Done linting! Found 9 violations, 2 serious in 1 file.</span><br><span class="line">husky &gt; pre-commit hook failed (add --no-verify to bypass)</span><br></pre></td></tr></table></figure>
<h3 id="如何解读错误？"><a href="#如何解读错误？" class="headerlink" title="如何解读错误？"></a>如何解读错误？</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">⛔️ Line 27: Line should be 120 characters or less: currently 218 characters</span><br></pre></td></tr></table></figure>
<p>此处是一处错误(error)，在 b.swift 文件中27行,该行长度超出约定，应该控制在 120 字符以内，现在是 218个，严重超标，请立即进行修改。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">⚠️ Line 40: Line should be 120 characters or less: currently 128 characters</span><br></pre></td></tr></table></figure>
<p>此处是一处警告(warning)，在 b.swift 文件中40行开始。该行长度超出约定，应该控制在 120 字符以内，现在是 128个，请注意。</p>
<h2 id="修复"><a href="#修复" class="headerlink" title="修复"></a>修复</h2><p>根据命令行提示修复结束后，需要通过 <code>git add</code> 添加你修改好的文件（没有特殊要求 <code>git add .</code>即可）。<br>add 结束后，通过 git commit 进行提交即可通过。</p>
<p>更多教程可点击<a href="https://github.com/realm/SwiftLint/blob/master/README_CN.md" target="_blank" rel="noopener">SwiftLint 中文说明</a>的规则部分查看。</p>
<h2 id="feat-分支开发及合并流程【初稿】"><a href="#feat-分支开发及合并流程【初稿】" class="headerlink" title="feat 分支开发及合并流程【初稿】"></a>feat 分支开发及合并流程【初稿】</h2><p><strong>note</strong></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">下文可能会涉及到 git rebase 的使用，在不熟悉的情况下请遵守以下黄金法则。</span><br><span class="line">1. develop、master、hotfix等多人共用分支请勿直接提交任何 commit，只用于日常的代码拉取和合并。</span><br><span class="line">2. 如果某次操作间隔中发生1的情况，请勿使用 rebase 合并线上代码到本地。</span><br><span class="line">3. rebase 仅限于 1、2、条件满足时的远程代码同步，例如：git rebase origin&#x2F;develop(分支名)</span><br></pre></td></tr></table></figure>

<ol>
<li><p>抓取线上代码到本地镜像</p>
<blockquote>
<p>这里需要注意，在代码合并前推荐对远程仓库镜像进行抓取，方便后续在合并时根据情况自由的选择合并的方式，选择不同的方式合并，产生的 git log 和分支合并痕迹也是不同的。</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git fetch origin develop <span class="comment"># 抓取主机名为 origin 下的远程仓库的 develop</span></span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 其中 origin 和 develop 为可选参数，用于更精确的数据抓取, zsh 可配置缩写为 gfod</span></span><br></pre></td></tr></table></figure></li>
<li><p>合并镜像分支到本地</p>
<blockquote>
<p>a. 这里本地分支主要指纯洁的没有本地提交过的公共分支(master、develop、hotfix等)，及其他私有分支(feat/xxx，fix/xxx)。</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 公共分支更新</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git checkout develop <span class="comment"># zsh 缩写为 gco develop</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git rebase origin/develop <span class="comment"># rebase 合并镜像分支 origin/develop 到本地 develop , zsh 为 grb origin/develop</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 私有分支更新</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git checkout feat/xxxx</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git rebase origin/develop</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>b. 如果 a 中公共分支不纯洁，则采用 git merge 进行分支合并</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git checkout develop</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git merge origin/develop <span class="comment"># 使用 merge 合并</span></span></span><br></pre></td></tr></table></figure>
</li>
<li><p>feat、fix 分支创建及开发</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 基于当前的分支创建私有分支</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git checkout develop</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git checkout -b feat/xxxx</span></span><br></pre></td></tr></table></figure>
<p>开发</p>
<blockquote>
<p>这里需要注意规范 commit message 的信息，可使用 git cz 进行控制，后续会讲到用法</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> git add .</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git cz <span class="comment"># 根据提示输入选项</span></span></span><br></pre></td></tr></table></figure>
</li>
<li><p>私有分支合并主干分支<br> a. 使用 gitlab 进行 merge request 申请，并勾选 squash commit。</p>
</li>
</ol>
<h1 id="git-提交的一些陋习及解决方案"><a href="#git-提交的一些陋习及解决方案" class="headerlink" title="git 提交的一些陋习及解决方案"></a>git 提交的一些陋习及解决方案</h1><p>to be continue…  </p>

    </div>

    
    
    
        

  <div class="followme">
    <p>欢迎关注我的其它发布渠道</p>

    <div class="social-list">

        <div class="social-item">
          <a target="_blank" class="social-link" href="https://www.jianshu.com/u/f37a8f0ba6f8">
            <span class="icon">
              <i class="fas fa-book"></i>
            </span>

            <span class="label">简书</span>
          </a>
        </div>
    </div>
  </div>


      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/%E5%B7%A5%E7%A8%8B%E7%AE%A1%E7%90%86/" rel="tag"># 工程管理</a>
              <a href="/tags/DevOps/" rel="tag"># DevOps</a>
              <a href="/tags/lint/" rel="tag"># lint</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2019/08/18/iOS%20%20lint%20%E8%87%AA%E5%8A%A8%E5%8C%96%E8%AF%95%E6%B0%B4/" rel="prev" title="iOS  lint 自动化试水">
      <i class="fa fa-chevron-left"></i> iOS  lint 自动化试水
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/03/22/%E5%9C%A8%20macOS%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20Visual%20Studio%20Code%EF%BC%88VSCode%EF%BC%89%E5%BC%80%E5%8F%91%20Swift/" rel="next" title="在 macOS 中使用 Visual Studio Code（VSCode）开发 Swift">
      在 macOS 中使用 Visual Studio Code（VSCode）开发 Swift <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          
    <div class="comments" id="valine-comments"></div>

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#gitflow-进阶规范"><span class="nav-number">1.</span> <span class="nav-text">gitflow 进阶规范</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#git-cz"><span class="nav-number">1.1.</span> <span class="nav-text">git cz</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#git-commit-的讲究"><span class="nav-number">1.1.1.</span> <span class="nav-text">git commit 的讲究</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#优点"><span class="nav-number">1.1.1.1.</span> <span class="nav-text">优点</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#husky-（自动化神器，git-hook-完美辅助）"><span class="nav-number">1.2.</span> <span class="nav-text">husky （自动化神器，git hook 完美辅助）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#lint-staged"><span class="nav-number">1.3.</span> <span class="nav-text">lint-staged</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#问题及bug处理"><span class="nav-number">1.4.</span> <span class="nav-text">问题及bug处理</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#参考"><span class="nav-number">1.4.1.</span> <span class="nav-text">参考</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#github-flow-VS-gitlab-flow-【三稿】"><span class="nav-number">2.</span> <span class="nav-text">github-flow VS gitlab-flow 【三稿】</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#git-flow"><span class="nav-number">2.1.</span> <span class="nav-text">git flow</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#master"><span class="nav-number">2.1.1.</span> <span class="nav-text">master</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#develop"><span class="nav-number">2.1.2.</span> <span class="nav-text">develop</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#feature-branches"><span class="nav-number">2.1.3.</span> <span class="nav-text">feature branches</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#release-branches"><span class="nav-number">2.1.4.</span> <span class="nav-text">release branches</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#hotfix-branches"><span class="nav-number">2.1.5.</span> <span class="nav-text">hotfix branches</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#GitHub-Flow"><span class="nav-number">2.2.</span> <span class="nav-text">GitHub Flow</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Gitlab-flow"><span class="nav-number">2.2.1.</span> <span class="nav-text">Gitlab flow</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#选出最合适的分支策略"><span class="nav-number">2.3.</span> <span class="nav-text">选出最合适的分支策略</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#SwiftLint-使用"><span class="nav-number">3.</span> <span class="nav-text">SwiftLint 使用</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#lint-成功"><span class="nav-number">3.1.</span> <span class="nav-text">lint 成功</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#lint-失败"><span class="nav-number">3.2.</span> <span class="nav-text">lint 失败</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#如何解读错误？"><span class="nav-number">3.2.1.</span> <span class="nav-text">如何解读错误？</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#修复"><span class="nav-number">3.3.</span> <span class="nav-text">修复</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#feat-分支开发及合并流程【初稿】"><span class="nav-number">3.4.</span> <span class="nav-text">feat 分支开发及合并流程【初稿】</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#git-提交的一些陋习及解决方案"><span class="nav-number">4.</span> <span class="nav-text">git 提交的一些陋习及解决方案</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="SuperYang"
      src="https://tva2.sinaimg.cn/crop.259.17.290.290.180/c2abdfa9jw8ez7appr3p2j20g40a2t91.jpg?KID=imgbed,tva&Expires=1594186820&ssig=BdxhDdi1Ti">
  <p class="site-author-name" itemprop="name">SuperYang</p>
  <div class="site-description" itemprop="description">牛肉炒饭不要香菜，老板收钱</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">39</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">31</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/yangchao0033" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;yangchao0033" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:ygrfwyc@gmail.com" title="E-Mail → mailto:ygrfwyc@gmail.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://weibo.com/yangchao0033" title="Weibo → https:&#x2F;&#x2F;weibo.com&#x2F;yangchao0033" rel="noopener" target="_blank"><i class="fab fa-weibo fa-fw"></i>Weibo</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://www.jianshu.com/u/f37a8f0ba6f8" title="简书 → https:&#x2F;&#x2F;www.jianshu.com&#x2F;u&#x2F;f37a8f0ba6f8" rel="noopener" target="_blank"><i class="fas fa-book fa-fw"></i>简书</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://t.me/superYang0033" title="Telegram → https:&#x2F;&#x2F;t.me&#x2F;superYang0033" rel="noopener" target="_blank"><i class="fab fa-telegram fa-fw"></i>Telegram</a>
      </span>
  </div>



      </div>

      
        <div id="music163player">
        <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=350 height=86 src="//music.163.com/outchain/player?type=2&id=31473269&auto=0&height=66">
        </iframe>
        </div>
    </div>

    

  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">SuperYang</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-area"></i>
    </span>
    <span title="站点总字数">157k</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
    <span title="站点阅读时长">2:23</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>




  
<script src="/js/local-search.js"></script>













  

  

  

  <script async src="/js/cursor/fireworks.js"></script>



<script>
NexT.utils.loadComments(document.querySelector('#valine-comments'), () => {
  NexT.utils.getScript('//unpkg.com/valine/dist/Valine.min.js', () => {
    var GUEST = ['nick', 'mail', 'link'];
    var guest = 'nick,mail,link';
    guest = guest.split(',').filter(item => {
      return GUEST.includes(item);
    });
    new Valine({
      el         : '#valine-comments',
      verify     : true,
      notify     : true,
      appId      : 'zizRqalUJY55Xc5oBJKbhxpV-gzGzoHsz',
      appKey     : '64gPcVi8lIA8zVGpBSEk7uKu',
      placeholder: "留言板无需注册登录，快来评论吧。。",
      avatar     : 'mm',
      meta       : guest,
      pageSize   : '10' || 10,
      visitor    : true,
      lang       : '' || 'zh-cn',
      path       : location.pathname,
      recordIP   : false,
      serverURLs : ''
    });
  }, window.Valine);
});
</script>

</body>
</html>
